<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>

<body>
    <script>
        const data = {
            text: 'hello world',
            ok: false
        }
        let activeEffect
            // const bucket = new Set() // 副作用函数的桶
        const bucket = new WeakMap() // 副作用函数的桶 使用WeakMap

        function effect(fn) {
            activeEffect = fn
            fn() // 执行副作用函数
        }

        const obj = new Proxy(data, {
            get(target, p, receiver) {
                track(target, p)
                return Reflect.get(...arguments)
            },
            set(target, p, value, receiver) {
                Reflect.set(...arguments) // 设置属性值
                trigger(target, p) // 把副作用函数取出并执行
                return Reflect.set(...arguments)
            }
        })

        // track函数
        function track(target, key) {
            if (!activeEffect) return target[key] // 没有正在执行的副作用函数 直接返回
            let depsMap = bucket.get(target)
            if (!depsMap) { // 不存在，则创建一个Map
                bucket.set(target, depsMap = new Map())
            }
            let deps = depsMap.get(key) // 根据key得到 depsSet(set类型), 里面存放了该 target-->key 对应的副作用函数
            if (!deps) { // 不存在，则创建一个Set
                depsMap.set(key, (deps = new Set()))
            }
            deps.add(activeEffect) // 将副作用函数加进去
        }

        // trigger函数
        function trigger(target, key) {
            const depsMap = bucket.get(target) // target Map
            if (!depsMap) return;
            const effects = depsMap.get(key) // effectFn Set
            effects && effects.forEach(fn => fn())
        }

        effect(() => {
            console.log('effect run')
            document.body.innerHTML = obj.ok ? obj.text : "none"
        })

        setTimeout(() => {
            obj.text = 'heeeeeeeeee'
        }, 1000)
    </script>
</body>

</html>